package com.example.mybatisstudy.service;

import com.example.mybatisstudy.mapper.ArticleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;

@Service
public class TransactionService {

    private static final Map map = new HashMap<>();
    @Autowired
    private DataSourceTransactionManager manager;
    @Autowired
    private TransactionDefinition definition;
    @Autowired
    private ArticleMapper articleMapper;
    public Object shoudong(Integer id) {
        //没有事务的情况下，1/0报错还是会执行删除
//        int num = articleMapper.del(id);
//        int x = 1/0;
        //添加事务以后：
        //1.开启事务
        TransactionStatus status = manager.getTransaction(definition);
        try {
            int num = articleMapper.del(id);
            int x = 1/0;
            manager.commit(status);//2.执行成功提交事务
        } catch (Exception e) {
            //3.回滚
            manager.rollback(status);
            throw new RuntimeException(e);
        }
        return map;
    }

    //声明式事务：属于aop的实现（spring-tx实现的）
    @Transactional
    public Object shengming(Integer id) {
        int num = articleMapper.del(id);
        int x = 1/0;
        return map;
    }

    @Transactional
    public Object shengming2(Integer id) {
        //以下代码就不能回滚：
        int num = articleMapper.del(id);
        try {
            int x = 1/0;
        } catch (Exception e) {
            //这样的代码，就算内部的异常已经处理掉，整个方法当作是正常返回
            e.printStackTrace();
        }
        return map;
    }

    @Transactional
    public Object shengming3(Integer id) {
        //以下代码能回滚：
        int num = articleMapper.del(id);
        try {
            int x = 1/0;
        } catch (Exception e) {
            //这样的代码，就算方法抛异常
            throw new RuntimeException(e);
        }
        return map;
    }

    //service一般可以怎么写业务逻辑处理：service调用service/mapper
    @Transactional
    public Object required1(){
        int num = articleMapper.del(5);
        //开启事务A，在required2中，会加入事务A
        return required2();
    }

    @Transactional
    public Object required2(){
        int num = articleMapper.del(6);
        int x = 1/0;
        return map;
    }

    @Transactional(propagation = Propagation.NESTED)
    public Object nested1(){
        int num = articleMapper.del(5);
        //开启事务A，在required2中，会加入事务A
        return nested2();
    }

    @Transactional(propagation = Propagation.NESTED)
    public Object nested2(){
        int num = articleMapper.del(6);
        int x = 1/0;
        return map;
    }
}
